package net.pws.common.security.filter;

import java.io.IOException;

import javax.servlet.FilterChain;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import net.pws.common.util.StringUtils;
import net.pws.common.security.spi.resource.CachedResourceManagerFactory;
import net.pws.common.security.spi.resource.ICachedResource;
import net.pws.common.security.spi.resource.IResource;
import net.pws.common.security.spi.resource.Resource;
import net.pws.common.security.spi.resource.ResourceDefinitionRepository;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;


/**
 *
 */
public class AuthenticatedUrlProcessor extends AbstractAuthenticateFilter {

	private static final Log logger = LogFactory
			.getLog(AuthenticatedUrlProcessor.class);

	public void doFilter(ServletRequest request, ServletResponse response,
			FilterChain chain) throws IOException, ServletException {

		if (!(request instanceof HttpServletRequest)) {
			throw new ServletException("Can only process HttpServletRequest");
		}

		if (!(response instanceof HttpServletResponse)) {
			throw new ServletException("Can only process HttpServletResponse");
		}

		HttpServletRequest httpRequest = (HttpServletRequest) request;
		HttpServletResponse httpResponse = (HttpServletResponse) response;

		if (null != request.getAttribute(AUTHENTICATED_SUCCEED_KEY)) {
			sendRedirect(httpRequest, httpResponse,
					getSucceedPageUrl(httpRequest));
			return;
		}

		String uri = httpRequest.getRequestURI();
		if (isSecurityUri(uri) && !allowedUrl(uri)) {
			sendRedirect(httpRequest, httpResponse, getNoPermissionPage());
			return;
		}

		chain.doFilter(request, response);
	}
	
	private boolean allowedUrl(String url) {
		if (StringUtils.isBlank(url)) {
			return true;
		}
		String userId = currentUserId();
		if (StringUtils.isBlank(userId)) {
			return false;
		}
		try {
			ICachedResource cachedResource = CachedResourceManagerFactory
					.getInstance().getObject().getCachedResource(userId);
			return cachedResource.allowedUrl(url);
		} catch (Exception e) {
			return false;
		}
	}


	private boolean isSecurityUri(String uri) {
		if (StringUtils.isBlank(uri)) {
			return false;
		}

		Resource[] allResources = ResourceDefinitionRepository.getInstance()
				.getAllResources();
		for (IResource resource : allResources) {
			if (uri.equals(resource.getUrl())) {
				return true;
			}
		}

		return false;
	}

	private String getSucceedPageUrl(HttpServletRequest request) {
		String referer = request.getHeader("Referer");
		if(referer == null) {
			return getHomePage();
		}
		
		String page = request.getParameter("page");
		if (StringUtils.isBlank(page)) {
			return getHomePage();
		}
		
		return page;
	}
}
